/*
 * Marshall.cpp
 *
 *  Created on: 06-11-2008
 *      Author: christian
 */

#include "dbus/dbus.h"
#include "Marshal.h"
#include <iostream>
#include <vector>
#include "XanguliException.h"

namespace Xanguli {

/*
int dbus_type(unsigned int& ui) {
	return DBUS_TYPE_UINT32;
}
int dbus_type(int& i) {
	return DBUS_TYPE_INT32;
}

int dbus_type(Variant& v) {
	return DBUS_TYPE_VARIANT;
}

int dbus_type(std::string& s) {
	return DBUS_TYPE_STRING;
}
*/

void serialize(DBusMessageIter* iter, std::string s){
	const char* c = s.c_str();
	dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &c);
}

void serialize(DBusMessageIter* iter, Variant v) {
	dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT32, &v);
}

void deserialize(DBusMessageIter* iter, unsigned int& ui) {
	if (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_UINT32) {
		dbus_message_iter_get_basic(iter, &ui);
		dbus_message_iter_next(iter);
	} else {
		throw new XanguliException("Signature mismatch\n");
	}
}

void deserialize(DBusMessageIter* iter, int& i) {
	if (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_INT32) {
		dbus_message_iter_get_basic(iter, &i);
		dbus_message_iter_next(iter);
	} else {
		throw new XanguliException("Signature mismatch\n");
	}
}

void deserialize(DBusMessageIter* iter, std::string& s) {
	std::cout << "Ind i deserialize(string)\n";
	if (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_STRING) {
		char* val;
		dbus_message_iter_get_basic(iter, &val);
		dbus_message_iter_next(iter);
		s = val;
	}
	else {
		std::cout << "Sig mismatch, expected " << (char) DBUS_TYPE_STRING << "\n";
		std::cout << "- but got " << (char) dbus_message_iter_get_arg_type(iter) << "\n";
		std::cout.flush();
		throw new XanguliException("Signature mismatch\n");
	}
}

void deserialize(DBusMessageIter* iter, Variant& v) {
	std::cout << "Deserialize Variant\n";
	if (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_VARIANT) {
		DBusMessageIter sub;
		dbus_message_iter_recurse(iter, &sub);
		switch (dbus_message_iter_get_arg_type(&sub)) {
		case DBUS_TYPE_UINT32:
			deserialize(&sub, v.ui);
			v.type = DBUS_TYPE_UINT32;
			std::cout << "Got: " << v.ui << "\n";
			break;
		case DBUS_TYPE_INT32:
			deserialize(&sub, v.i);
			v.type = DBUS_TYPE_UINT32;
			std::cout << "Got: " << v.i << "\n";
			break;
		case DBUS_TYPE_STRING:
			dbus_message_iter_get_basic(&sub, &(v.s));
			dbus_message_iter_next(&sub);
			v.type = DBUS_TYPE_STRING;
			std::cout << "Got: " << v.s << "\n";
			break;
		default:
			throw new XanguliException("Xanguli only supports unsigned ints, ints and strings in variants\n");
		}
	} else {
		throw new XanguliException("Signature mismatch\n");
	}
	std::cout << "Leaving deserialize(,Variant), v = " << v.asString() << "\n";
}

}
